# modules/emotion_detection.py
import json
import os
import subprocess
import time
from datetime import datetime
from typing import Dict, Any, Optional
from .ai_qa import DS  # 导入同目录下的AI模型接口


class EmoDetector:
    def __init__(self, weather_script_path="weather.py"):
        # 获取项目根目录（确保无论从何处运行，均指向项目根）
        self.project_root = os.path.abspath(os.path.join(
            os.path.dirname(__file__),  # modules目录
            ".."  # 回退到项目根目录
        ))
        self.weather_script_path = os.path.join(
            self.project_root, "modules", weather_script_path  # 完整路径
        )
        self.system_prompt = """
        你是一个专业的情绪分析师。根据用户的回复、用户历史数据和当前天气信息，
        分析用户的情绪状态。请以JSON格式输出分析结果，包含以下字段：
        - emotion: 主要情绪（如happy, sad, angry, neutral, excited, anxious等）
        - confidence: 分析的置信度（0.0-1.0）
        - intensity: 情绪强度（1-5，5表示最强）
        - contributing_factors: 影响情绪的因素列表
        - suggestion: 基于情绪分析的建议
        """
        # 获取项目根目录（假设modules的父目录是项目根）
        self.project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

    def get_weather_data(self, city: str) -> bool:
        """通过subprocess调用weather.py获取天气数据"""
        try:
            # 使用二进制模式捕获输出，避免立即解码
            result = subprocess.run(
                ["python", self.weather_script_path, city],
                cwd=self.project_root,
                capture_output=True,
                text=False  # 关键修改：使用二进制模式
            )

            # 检查返回码
            if result.returncode != 0:
                # 尝试以多种编码解码错误信息
                try:
                    stderr = result.stderr.decode('utf-8')
                except UnicodeDecodeError:
                    stderr = result.stderr.decode('gbk', errors='replace')
                print(f"天气获取失败: {stderr}")
                return False

            # 尝试自动检测输出编码
            try:
                # 优先尝试 UTF-8
                output = result.stdout.decode('utf-8')
            except UnicodeDecodeError:
                # 回退到 GBK
                output = result.stdout.decode('gbk', errors='replace')

            print(f"天气脚本输出: {output[:200]}...")  # 打印前200个字符用于调试
            return self._wait_for_weather_file()

        except Exception as e:
            print(f"调用weather脚本异常: {str(e)}")
            return False

    def _wait_for_weather_file(self, timeout=10) -> bool:
        """等待天气文件生成"""
        file_path = os.path.join(self.project_root, "temp", "temp.json")
        start_time = time.time()
        while time.time() - start_time < timeout:
            if os.path.exists(file_path) and os.path.getsize(file_path) > 10:
                return True
            time.sleep(0.5)
        print(f"警告: 超时未找到天气文件 - {file_path}")
        return False

    def load_weather_data(self) -> Dict[str, Any]:
        """加载天气数据"""
        file_path = os.path.join(self.project_root, "temp", "temp.json")
        try:
            with open(file_path, 'r', encoding='gbk') as f:  # 使用gbk编码读取
                data = json.load(f)
            return data["weatherlist"][0]  # 使用第一天的天气数据
        except json.JSONDecodeError as e:
            print(f"JSON解析错误: {str(e)}")
            print(f"文件内容可能损坏: {file_path}")
            return {"error": "weather_parse_failed"}
        except Exception as e:
            print(f"加载天气数据失败: {str(e)}")
            return {"error": "weather_load_failed"}

    def prepare_prompt(self, user_response: str, user_data: Dict[str, Any], weather_data: Dict[str, Any]) -> str:
        """生成AI分析提示词"""
        weather_info = (
            f"天气：{weather_data.get('climate1', '未知')}，"
            f"温度：{weather_data.get('low', '未知')}~{weather_data.get('high', '未知')}，"
            f"风向：{weather_data.get('windDirection1', '未知')}{weather_data.get('windPower1', '未知')}"
        ) if "error" not in weather_data else "天气数据不可用"

        return (
            f"用户回复：{user_response}\n\n"
            f"用户信息：{json.dumps(user_data, ensure_ascii=False)}\n\n"
            f"当前天气：{weather_info}\n\n"
            f"{self.system_prompt}\n请严格按照JSON格式返回结果"
        )

    def emotion_detection(
            self,
            user_response: str,
            user_data: Dict[str, Any],
            city: str
    ) -> Optional[Dict[str, Any]]:
        """主情绪分析流程"""
        # 1. 获取天气数据
        if not self.get_weather_data(city):
            # 天气获取失败时，提供默认天气数据继续流程
            print("使用默认天气数据继续分析...")
            weather_data = {
                "climate1": "未知",
                "low": "未知",
                "high": "未知",
                "windDirection1": "未知",
                "windPower1": "未知"
            }
        else:
            # 2. 加载天气数据
            weather_data = self.load_weather_data()
            if "error" in weather_data:
                print(f"天气数据异常：{weather_data['error']}")
                print("使用默认天气数据继续分析...")
                weather_data = {
                    "climate1": "未知",
                    "low": "未知",
                    "high": "未知",
                    "windDirection1": "未知",
                    "windPower1": "未知"
                }

        # 3. 生成提示词并调用AI模型
        prompt = self.prepare_prompt(user_response, user_data, weather_data)
        prompt = self.prepare_prompt(user_response, user_data, weather_data)
        try:
            ai_response = DS(prompt+"用中文回答")
            print(f"AI原始响应: {ai_response}")  # 调试用，查看是否有多余标记

            # 清理Markdown代码块标记（```json 和 ```）
            cleaned_response = ai_response.strip()
            if cleaned_response.startswith("```json"):
                cleaned_response = cleaned_response[len("```json"):].strip()
            if cleaned_response.endswith("```"):
                cleaned_response = cleaned_response[:-len("```")].strip()

            emotion_result = json.loads(cleaned_response)
        except json.JSONDecodeError as e:
            print(f"AI响应清理后: {cleaned_response}")  # 查看清理后的内容
            print(f"JSON解析错误: {str(e)}")
            # 失败时返回默认情绪分析结果
            print("使用默认情绪分析结果...")
            emotion_result = {
                "emotion": "neutral",
                "confidence": 0.5,
                "intensity": 2,
                "contributing_factors": ["数据不足"],
                "suggestion": "建议提供更多信息"
            }

        except Exception as e:
            print(f"AI分析失败：{str(e)}")
            return None

        # 4. 组装结果
        return {
            "user_id": user_data["user_id"],
            "analysis_time": datetime.now().isoformat(),
            "user_response": user_response,
            "weather_data": weather_data,
            "emotion_analysis": emotion_result
        }

